# -*- coding: utf-8 -*-
from Tkinter import *
from time import sleep
import urllib
from HttpClient import HttpClient
import requests
import json,io,time,os
from multiprocessing import Process
import multiprocessing
import random,datetime
from PIL import Image, ImageTk
sys.path.append("..")
import resolve
msgsrv = resolve.MessageServer()
class WebQQ(HttpClient):
    def __init__(self):
        self.__histry_list = ""
        self.__t_search = {}
        self.__cookie = ""
        self.__ptwebqq = ""
        self.__pgv_pvid = ""
        self.__ts_uid = ""
        self.__pgv_info = ""
        self.__vfwebqq = ""
        self.__hash = ""
        self.__uin = ""
        self.__root = ""
        self.__psessionid = ""
        self.queue = multiprocessing.Queue()
        self.temp=''
        self.ptqrtoken = ""
        self.__admin_group = ""
    def hash32(self,qrsig):
        e = 0
        for i in range(len(qrsig)):
            e+=(e<<5)+ord(unicode(qrsig[i]))
        return 2147483647 & e
    #获取二维码
    def __ptqrshow(self):
        img = self.Get(url="https://ssl.ptlogin2.qq.com/ptqrshow?appid=501004106&e=0&l=M&s=5&d=72&v=4&t=0.4139144900254905")
        print "qrsig:",self.getCookie("qrsig"),self.hash32(self.getCookie("qrsig"))
        self.ptqrtoken = self.hash32(self.getCookie("qrsig"))
        if(img!=None):
            data_stream = io.BytesIO(img)
            imgfile = Image.open(data_stream)
            p = Process(target=self._run_proc, args=(imgfile,))
            p.start()
            print("二维码下载完毕，请尽快扫描...")
            return True
        else:
            print("二维码下载失败")
            return False

    #检测扫码状态，登录进度
    def __ptqrlogin(self):
        #print "cookies:",self.__cookie
        res = self.Get("https://ssl.ptlogin2.qq.com/ptqrlogin?ptqrtoken="+str(self.ptqrtoken)+"&webqq_type=10&remember_uin=1"+
                       "&login2qq=1&aid=501004106&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10"+
                       "&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-136435"+
                       "&mibao_css=m_webqq&t=undefined&g=1&js_type=0&js_ver=10139&login_sig=&pt_randsalt=0",
                       "https://ui.ptlogin2.qq.com/cgi-bin/login")

        #res = self.Get("https://ssl.ptlogin2.qq.com/ptqrlogin?ptqrtoken=501004106&webqq_type=10&remember_uin=1&login2qq=1&aid=501004106&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&mibao_css=m_webqq&t=undefined&g=1&js_type=0&js_ver=10199&login_sig=&pt_randsalt=0", "https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=16&mibao_css=m_webqq&appid=501004106&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fw.qq.com%2Fproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=20131024001")
        print res
        if(res!=None):
            result = res.find("登录成功")

            if(result==-1):
                sleep(1)

                return self.__ptqrlogin()
            elif(result!=-1):
                res = res.decode("UTF-8")
                self.temp = res[res.find("http"):res.find(u"','0','登录成功！'")].encode()
                return self.__check_sig(res[res.find("http"):res.find(u"','0','登录成功！'")].encode())
            else:
                return False
        else:
            return False
    def get_online_buddies(self):
        print "http://d1.web2.qq.com/channel/get_online_buddies2?vfwebqq=%s&clientid=53999199&psessionid=%s&t=1507981963969"%(self.__vfwebqq,self.__psessionid)
        res = self.Get("http://d1.web2.qq.com/channel/get_online_buddies2?vfwebqq=%s&clientid=53999199&psessionid=%s&t=1507981963969"%(self.__vfwebqq,self.__psessionid))
        print "gob:::",res
    #获得ptwebqq  cookie
    def __check_sig(self,url):
        res = self.Get(url=url,refer="https://ui.ptlogin2.qq.com/cgi-bin/login")
        if(res!=None):
            self.__ptwebqq = self.getCookie("ptwebqq")
            print self.__ptwebqq
            self.__getvfwebqq()
            return self.__login2()
        else:
            return False
    #获得vfwebqq  cookie
    def __getvfwebqq(self):
        res = self.Get(url="http://s.web2.qq.com/api/getvfwebqq?ptwebqq="+self.__ptwebqq+
                       "&clientid=53999199&psessionid=&t=1446710396202",
                     refer="http://d.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1")
        if(res!=None):
            jsn = json.loads(res)
            self.__vfwebqq = jsn["result"]["vfwebqq"]
            self.Tem_Cookies = self.getCookies()
    #登录 获取uin psessionid
    def __login2(self):
        data = "r=%7B%22ptwebqq%22%3A%22"+self.__ptwebqq+"%22%2C%22clientid%22%3A53999199%2C%22psessionid%22%3A%22%22%2C%22status%22%3A%22online%22%7D"

        res = self.Post(url = "http://d1.web2.qq.com/channel/login2",
                        data = data.encode(encoding="utf8"),
                        refer = "http://d.web2.qq.com/proxy.html?v=20130916001&callback=1&id=2")
        if(res==None):
            return False
        jsn = json.loads(res)
        if(jsn["retcode"]==0):
            self.__uin = jsn["result"]["uin"]
            self.__psessionid = jsn["result"]["psessionid"]
            self.__hash = self.__friendsHash(self.__uin,self.__ptwebqq)
            self.__get_user_friends()

            self._groups = self.__get_group_name_list_mask2()
            for i in self._groups:
                if i["name"] == u"细小胖次元的怠惰势力":
                    self.__admin_group = i["gid"]
            print "admin::",self.__admin_group
            self._get_group_info_ext2(self.__admin_group)
            self.get_online_buddies()
            #print "CK:",self.getCookies()
            #self._get_group_info_ext2("2231140313",123456)

            return True
        else:
            return False
    #好友的hash  参考HexBlog
    def __friendsHash(self,uin,pt):
        N=[0 for x in range(4)]
        V=[0 for x in range(4)]
        U=[0 for x in range(8)]
        #    字符串转换为字符数组
        k=pt.encode(encoding="UTF8")
        n=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]
        for x in range(len(k)):
            N[x%4]^=ord(k[x])
        x=int(uin)
        V[0] = x >> 24 & 255 ^ 69;
        V[1] = x >> 16 & 255 ^ 67;
        V[2] = x >> 8 & 255 ^ 79;
        V[3] = x & 255 ^ 75;
        for x in range(8):
            U[x]=(x%2==0) and N[x>>1] or V[x>>1]
        result=""
        for x in U:
            result+=n[x>>4&15]
            result+=n[x&15]
        return result
    def __get_group_name_list_mask2(self):#所有群uin都在这里，发群消息得查这个
        data="r=%7B%22vfwebqq%22%3A%22"+self.__vfwebqq+"%22%2C%22hash%22%3A%22"+self.__hash+"%22%7D"
        res=self.Post(url="http://s.web2.qq.com/api/get_group_name_list_mask2",
                       data=data.encode(encoding="utf8"),
                         refer="http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1")
        print("Group_List:",res)
        if(res!=None):
            #    记录群列表
            jsn=json.loads(res)
            return jsn["result"]["gnamelist"]
    #从群列表中查看名字
    def __saerch_name_for_user_uin(self,form_uin,user_):
        print("Search",form_uin,user_)
        if form_uin in self.__t_search:
            if self.__t_search[form_uin]>=3:
                print("Get QunList Error:"+str(form_uin))
                return user_
            else:
                self.__t_search[form_uin]+=1
        else:
            self.__t_search[form_uin] = 0
        if os.path.isfile(form_uin+".lists"):
            print "File in",form_uin
            with open(form_uin+".lists","r") as f:
                jsn = json.loads(f.read())
                for i in jsn["result"]["minfo"]:
                    if str(i["uin"]) == str(user_):
                        return i["nick"]
                return form_uin

        else:
            self._get_group_info_ext2(form_uin)
            self.__saerch_name_for_user_uin(form_uin,user_)
            return user_
    #读取聊天记录文件
    def __load_text_histry(self):
        if os.path.isfile("histry"):
            with open("histry") as f:
                return f.read()
        else:
            return
    #写入聊天记录文件
    def __write_text_histry(self,text):
        if self.__histry_list<30:
            self.__histry_list.append(text)
        else:
            with open("histry","wb") as f:
                f.write("\n".join(self.__histry_list))
                self.__histry_list=[]

    #获取好友列表
    def __get_user_friends(self):
        data="r=%7B%22vfwebqq%22%3A%22"+self.__vfwebqq+"%22%2C%22hash%22%3A%22"+self.__hash+"%22%7D"
        res=self.Post(url="http://s.web2.qq.com/api/get_user_friends2",
                       data=data.encode(encoding="utf8"),
                         refer="http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1")

        if(res!=None):
            #    记录好友列表
            jsn=json.loads(res)
            if(jsn["retcode"]==0):
                #    正确返回列表后
                for x in jsn["result"]["info"]:#所有好友Uin都在这里！！！！所以想要发消息得查这个json!!!!!
                    print (x)

    def __send_buddy_msg2(self,uin,content):#发送消息
        data = 'r=%7B%22to%22:'+str(uin)+',%22content%22:%22%5B%5C%22'+urllib.quote(content)+'%5C%22,%5B%5C%22font%5C%22,%7B%5C%22name%5C%22:%5C%22%E5%AE%8B%E4%BD%93%5C%22,%5C%22size%5C%22:10,%5C%22style%5C%22:%5B0,0,0%5D,%5C%22color%5C%22:%5C%22000000%5C%22%7D%5D%5D%22,%22face%22:552,%22clientid%22:53999199,%22msg_id%22:96120001,%22psessionid%22:%22'+self.__ptwebqq+'%22%7D'
        #data = 'r= {"to":'+str(uin)+',"content":"["'+content+'",["font",{"name":"Microsoft HMei;","size":10,"style":[0,0,0],"color":"000000"}]]","face":0,"clientid":53999199,"msg_id":{'+'28520003'+'"psessionid":"'+self.__psessionid+'"}'.encode('utf-8')
        res=self.Post(url='http://d1.web2.qq.com/channel/send_buddy_msg2',
                      data=data,
                      refer='http://d1.web2.qq.com/proxy.html')
        print("QQ_QUN:",res)
    def __send_qun_msg2(self,uin,content):#发送群消息
        data = 'r=%7B%22group_uin%22:'+str(uin)+',%22content%22:%22%5B%5C%22'+urllib.quote(content)+'%5C%22,%5B%5C%22font%5C%22,%7B%5C%22name%5C%22:%5C%22%E5%AE%8B%E4%BD%93%5C%22,%5C%22size%5C%22:10,%5C%22style%5C%22:%5B0,0,0%5D,%5C%22color%5C%22:%5C%22000000%5C%22%7D%5D%5D%22,%22face%22:552,%22clientid%22:53999199,%22msg_id%22:39910001,%22psessionid%22:%22'+self.__psessionid+'%22%7D'
        res = self.Post(url='http://d1.web2.qq.com/channel/send_qun_msg2',
                data=data,
                refer = 'http://d1.web2.qq.com/proxy.html')
        print(res)
    #心跳包并接收消息
    def __poll(self):

        data="r:%7B%22ptwebqq%22%3A%22"+self.__ptwebqq+"%22%2C%22clientid%22%3A53999199%2C%22psessionid%22%3A%22"+self.__psessionid +"%22%2C%22key%22%3A%22%22%7D"
        r ='r= {"ptwebqq":"'+ self.__ptwebqq+'","clientid":53999199,"psessionid":"'+self.__psessionid+'","key":""}'
        res=self.Post(url="http://d1.web2.qq.com/channel/poll2",
                      data=data,
                      refer="http://d1.web2.qq.com/proxy.html")
        print("_poll",res)
        if(res!=None):
            jsn = json.loads(res)
            if(jsn['retcode'] == 0 and 'errmsg' not in jsn):
                if(jsn['result'][0]['poll_type'] == 'message'):
                    from_uin = jsn['result'][0]['value']['from_uin']
                    content = jsn['result'][0]['value']['content'][1].encode('utf-8')
                    #self.__send_buddy_msg2(str(from_uin)+'发送了:\n'+content)
                    self.MsgTask(from_uin,0,content)
                else:
                    from_uin = jsn['result'][0]['value']['from_uin']
                    content = jsn['result'][0]['value']['content'][1].encode('utf-8')
                    send_uin = jsn['result'][0]['value']['send_uin']
                    #self._get_group_info_ext2(from_uin,send_uin)
                    self.MsgTask(from_uin,send_uin,content)
    def txt_wrap_by(self,start_str, end, html):
        start = html.find(start_str)
        if start >= 0:
            start += len(start_str)
            end = html.find(end, start)
            if end >= 0:
                return html[start:end].strip()
    def url(self,reg,web):#正则表达式运用部分
        reg_href = re.compile(reg)
        allpost = reg_href.findall(web,re.S)
        return allpost
    def MsgTask(self,from_uin,send_uin,res):#处理消息，执行命令
        if res=="getHistry":
            return self.__load_text_histry()
        if from_uin == 0 and send_uin == 0:
             self.__send_qun_msg2(self.__admin_group,msg)
        Name = self.__saerch_name_for_user_uin(str(from_uin),str(send_uin))
        print(Name+"--"+res)
        self.__write_text_histry(Name+"--"+res)
        msgsrv._poll_to_all_user(Name+"--"+res)




    def __check_queue(self):
        try:
            out = self.queue.get_nowait()
            if out == 'stop':
                self.__do_stop()
                return
            # Could check for other commands here, too
        except :
            pass
        self.__root.after(100, self.__check_queue)

    def __stop(self):
        self.queue.put('stop')

    def __do_stop(self):
        self.__root.destroy()
    def _get_group_info_ext2(self,form_uin):
        res = self.Get("http://s.web2.qq.com/api/get_group_info_ext2?gcode="+
                        str(form_uin)+"&vfwebqq="+self.__vfwebqq+"&t=1508318421738",
            refer="http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1")
        with open(str(form_uin)+".lists","wb") as f:
            f.write(res)
    def __d(self):
        return int(random.random()*2147483647)*(int(str(datetime.datetime.now().microsecond)[:-3])%10000000000)
    def _set_observer(self,obj):
        msgsrv._set_observer(obj)
    def _run_proc(self,imgfile):
        self.__root = Tk()
        result = ImageTk.PhotoImage(imgfile)
        label = Label(self.__root, image=result)
        label.pack()
        self.__root.after(100, self.__check_queue)
        self.__root.mainloop()
    def run(self):
        if(self.__ptqrshow()):

            if(self.__ptqrlogin()):
                print("登录成功")
                global Login

                Login = True

                #self.Out_SendGroupMsg("消息发送测试")
                #self.__send_qun_msg2('3374463419','群消息发\n送测试')
                #self._get_group_info_ext2(1176250445,1191167532)
                while 1:#遍历消息
                    try:
                        self.__poll()
                    except:
                        pass
                    time.sleep(1)


if  __name__ =="__main__":
    qq=WebQQ()
    qq.run()
